package org.devf.fork.imsimulator.socket;

import java.nio.ByteBuffer;

public class TcpPacket {
	private TcpPacketLength m_PacketLength; //数据包长度部分
	private TcpPacketData m_PacketData;     //数据包数据部分

	public TcpPacket() {
		m_PacketLength = new TcpPacketLength();
	}

	public int append(byte[] vStream, int vOffset) {
		//优先填充长度部分
		int tOffset = vOffset;
		if(false == m_PacketLength.isComplete()) {
			tOffset = m_PacketLength.write(vStream, tOffset);

			//如果长度部分填充完成，则为数据部分分配空间
			if(false == m_PacketLength.isComplete())
				return tOffset;

			//判断是否长度异常
			int tDataLen = m_PacketLength.getLength();
			m_PacketData = new TcpPacketData(tDataLen);
		}

		//如果数据部分还需要填充，则填充数据部分
		if(true == m_PacketData.isComplete())
			return tOffset;

		return m_PacketData.write(vStream, tOffset);
	}

	public byte[] getData(){
		if(false == isComplete())
			return null;

		return m_PacketData.getData();
	}

	public boolean isComplete() {
		if(null == m_PacketData)
			return false;

		return m_PacketData.isComplete();
	}
}

class TcpStreamBase {
	private ByteBuffer m_Stream;
	private int m_Size;

	TcpStreamBase(final int vSize) {
		m_Size = vSize;
		m_Stream = ByteBuffer.allocate(vSize);
	}

	public int write(byte[] vStream, int vOffset) {
		int tSize = m_Size - m_Stream.position();
		if(tSize > vStream.length-vOffset)
			tSize = vStream.length-vOffset;

		m_Stream.put(vStream, vOffset, tSize);
		return vOffset+tSize;
	}

	public byte[] getData() {
		return m_Stream.array();
	}

	public boolean isComplete() {
		return m_Size == m_Stream.position();
	}
}

class TcpPacketLength extends TcpStreamBase{
	TcpPacketLength() {
		//协议规定数据包长度部分为4字节
		super(4);
	}

	@SuppressWarnings("OverlyComplexBooleanExpression")
	public int getLength() {
		byte[] tData = getData();
		return (tData[0] & 0xFF) | ((tData[1] & 0xFF)<<8) | ((tData[2] & 0xFF)<<16) | ((tData[3] & 0xFF)<<24);
	}
}

class TcpPacketData extends TcpStreamBase{
	TcpPacketData(final int vSize) {
		super(vSize);
	}
}
